////////////////////////////////////////////////////////////////////////////////
//Parser

use std::cell::RefCell;
use super::nscanner::Tokenizer;
use super::nast::Prog;
use super::nast::FunctionDecl;
use super::nast::FunctionBody;
use super::nast::FunctionCall;
use super::nast::Statements;
use super::nscanner::TokenKind;

/**
 * 语法解析器。
 * 通常用parseProg()作为入口，解析整个程序。也可以用下级的某个节点作为入口，只解析一部分语法。
 */
pub struct Parser  {
	tokenizer: Tokenizer
}

impl Parser{
	pub fn new(tokenizer:Tokenizer) -> Parser {
		Parser{
			tokenizer: tokenizer,
		}
	}

	/**
	 * 解析Prog
	 * 语法规则：
	 * prog = (functionDecl | functionCall)*
	 */
	pub fn parse_prog(&mut self) -> Prog {
		let mut stmts: Vec<Statements> = Vec::new();
		let mut stmt: Option<Statements>;
		let mut token = self.tokenizer.peek();

		//每次循环解析一个语句
		while !token.kind.eq(&TokenKind::EOF) {
			if token.kind.eq(&TokenKind::Keyword) && token.text.eq("function") {
				//先尝试一下函数声明
				stmt = Option::from(Statements::FunctionDecl(self.parse_function_decl().unwrap()));

				if stmt.is_some() {
					//读取成功压入stmts
					stmts.push(stmt.unwrap());
					println!("FunctionDecl added!");
				} else {
					//读取失败
					println!("parseFunctionDecl failed!!!");
				}

			} else if token.kind.eq(&TokenKind::Identifier) {
				//再尝试一下函数调用
				stmt = Option::from(Statements::FunctionCall(self.parse_function_call().unwrap()));

				if stmt.is_some() {
					//读取成功压入stmts
					stmts.push(stmt.unwrap());
					println!("FunctionCall added!");
				} else {
					//读取失败
					println!("parseFunctionCall failed!!!");
				}
			} else {
				println!("neither parseFunctionDecl nor parseFunctionCall!!!");
			}

			//下一个token
			token = self.tokenizer.peek();
		}

		return Prog::new(stmts);
	}

	/**
	 * 解析函数声明
	 * 语法规则：
	 * functionDecl: "function" Identifier "(" ")"  functionBody
	 */
	 pub fn parse_function_decl(&mut self) -> Option<FunctionDecl> {
		self.tokenizer.record_pos();
		let mut t = self.tokenizer.next();

		if t.kind.eq(&TokenKind::Keyword) && t.text.eq("function") {
			t = self.tokenizer.next();
			if t.kind.eq(&TokenKind::Identifier) {
				//读取"("和")"
				let t1 = self.tokenizer.next();
				if t1.text.eq("(") {
					let t2 = self.tokenizer.next();
					if t2.text.eq(")") {
						//尝试读取FunctionBody
						let function_body = self.parse_function_body();
						if function_body.is_some() {
							println!("parseFunctionBody successed!");
							//如果解析成功，从这里返回
							return Some(FunctionDecl::new(t.text, function_body));
						} else {
							println!("Error parsing FunctionBody in FunctionDecl");
							return None;
						}
					} else {
						//括号不匹配
						println!("Expecting ')' in FunctionDecl, while we got a {}" , t.text);
						return None;
					}
				} else {
					//函数声明格式不正确
					println!("Expecting '(' in FunctionDecl, while we got a {}" , t.text);
					return None;
				}
			}
		}

		//如果解析不成功，回溯，返回nil
        self.tokenizer.rollback_pos();
		println!("parseFunctionDecl traceBack!");
		return None;
	}

	/**
	 * 解析函数体
	 * 语法规则：
	 * functionBody : '{' functionCall* '}'
	 */
	pub fn parse_function_body(&mut self) -> Option<RefCell<FunctionBody>> {
		self.tokenizer.record_pos();
		let mut stmts:Vec<FunctionCall> = Vec::new();

		let mut t = self.tokenizer.next();
		if t.text.eq("{") {
			//从函数中读取一个个的FunctionCall
			let mut function_call = self.parse_function_call();
			//解析函数体
			while function_call.is_some() {
				stmts.push(function_call.unwrap());
				function_call = self.parse_function_call();
			}

			t = self.tokenizer.next();
			if t.text.eq("}") {
				//FunctionBody读取结束
				return Option::from(RefCell::new(FunctionBody::new(stmts)));
			} else {
				//花括号不匹配
				println!("Expecting '}}' in FunctionBody, while we got a {}" , t.text);
			}
		} else {
			//FunctionBody格式错误
			println!("Expecting '{{' in FunctionBody, while we got a {}" , t.text);
		}

		//如果解析不成功，回溯，返回nil。
		println!("parseFunctionBody traceBack!");
		self.tokenizer.rollback_pos();
		return None;
	}

	/**
	 * 解析函数调用
	 * 语法规则：
	 * functionCall : Identifier '(' parameterList? ')'
	 * parameterList : StringLiteral (',' StringLiteral)*
	 */
	pub fn parse_function_call(&mut self) -> Option<FunctionCall> {
		self.tokenizer.record_pos();
		let mut params:Vec<String> = Vec::new();
		let t = self.tokenizer.next();

		if t.kind==TokenKind::Identifier {
			let t1 = self.tokenizer.next();
			if t1.text.eq("(") {
				let mut t2 = self.tokenizer.next();
				//循环，读出所有参数
				while !t2.text.eq(")"){

					if t2.kind.eq(&TokenKind::StringLiteral) {
						//字符串参数
						params.push(t2.text);
					} else {
						//暂不支持其他类型参数
						println!("Expecting parameter in FunctionCall, while we got a {}" , t2.text);
						return None; //出错时，就不在错误处回溯了。
					}

					t2 = self.tokenizer.next();
					//参数部分未结束，分析其他参数
					if !t2.text.eq(")") {
						if t2.text.eq(",") {
							//其他参数
							t2 = self.tokenizer.next();
						} else {
							//格式错误
							println!("Expecting a comma in FunctionCall, while we got a {}" , t2.text);
							return None;
						}
					}
				}

				//参数获取完毕
				t2 = self.tokenizer.next();
				if t2.text.eq(";") {
					//消化掉一个分号：
					println!("parseFunctionCall successed!");
					return Some(FunctionCall::new(t.text, params));
				} else {
					//格式错误
					println!("Expecting a semicolon in FunctionCall, while we got a {}" , t2.text);
				}
			}
		}

		//如果解析不成功，回溯，返回nil。
		println!("parseFunctionCall traceBack!");
		self.tokenizer.rollback_pos();
		return None;
	}
}